'use strict';
const moment = require('moment');
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const BMP24 = require('gd-bmp').BMP24;
const lodash = require('lodash');
const qr = require('qr-image');

/*
 * 获取日期时间戳区间
 * @param int|string|array times
 * return {start_time,end_time}
 */
exports.get_between_time = times => {
  let start_time = 0;
  let end_time = this.date_to_time();
  const format = 'YYYY-MM-DD';
  // 最近n天
  if (lodash.isNumber(times)) {
    start_time = times ? moment().subtract(times, 'days').format(format) : moment().format(format);
    end_time = moment().add(1, 'days').format(format);
  }
  // 指定区间
  if (lodash.isArray(times)) {
    start_time = moment(times[0]).format(format);
    end_time = moment(times[1]).add(1, 'days').format(format);
  }
  // 指定时间单位
  if (lodash.isString(times)) {
    const str = times.toLowerCase();
    const w = moment().format('d');
    const m = moment().format('M');
    switch (str) {
      case 'today':
        start_time = moment().format(format);
        end_time = moment().add(1, 'days').format(format);
        break;
      case 'yesterday':
        start_time = moment().subtract(1, 'days').format(format);
        end_time = moment().format(format);
        break;
      case 'week':
        start_time = moment().subtract(w - 1, 'days').format(format);
        end_time = moment().add(1, 'days').format(format);
        break;
      case 'lastweek':
        start_time = moment().subtract(w + 7, 'days').format(format);
        end_time = moment().subtract(w - 1, 'days').format(format);
        break;
      case 'month':
        start_time = moment().subtract(m, 'days').format(format);
        end_time = moment().add(1, 'days').format(format);
        break;
      case 'lastmonth':
        start_time = moment().subtract(m, 'days').subtract(1, 'month').format(format);
        end_time = moment().subtract(m, 'days').format(format);
        break;
      default:
        break;
    }
  }
  if (start_time) {
    start_time = moment(start_time).unix();
  }
  if (end_time) {
    end_time = moment(end_time).unix();
  }
  return { start_time, end_time };
};

/*
* 日期格式转时间戳
* @param string time 格式,为空返回当前的时间戳
* @param int type 单位：0-s,1-ms
* return string
* For: exports.time_to_date('2018-8') => 1533052800
* */
exports.date_to_time = (format, type = 0) => {
  const flag = type ? 'x' : 'X';
  if (!format) {
    const time = new Date().getTime();
    return type ? time : Math.ceil(time / 1000);
  }
  return moment(format).format(flag);
};

/*
* 时间戳转日期格式
* @param int time 时间戳
* @param int format 格式类型
* return string
* For: exports.time_to_date(1533333333) => 2018-8-4
* */
exports.time_to_date = (time, format = 3) => {
  time = time ? time * 1000 : new Date().getTime();
  const format_list = ['YYYY-MM-DD', 'YYYY', 'MM-DD', 'YYYY-MM-DD', 'MM-DD HH:mm', 'YYYY-MM-DD HH:mm', 'YYYY-MM-DD HH:mm:SS'];
  return moment(time).format(format_list[format]);
};

/*
* md5加密
* @param string content 内容
* return string
* For: exports.md5('123456') => e10adc3949ba59abbe56e057f20f883e
* */
exports.md5 = content => {
  const md5 = crypto.createHash('md5');
  md5.update(new Buffer.from(String(content)));
  return md5.digest('hex');
};

/*
* base64加密
* @param string content 内容
* return string
* For: exports.base64_encode('123456') => MTIzNDU2
* */
exports.base64_encode = content => {
  if (content != null) {
    return new Buffer.from(content).toString('base64');
  }
};

/*
* base64解密
* @param string content base64字符串
* return string
* For: exports.base64_decode('MTIzNDU2') => MTIzNDU2
* */
exports.base64_decode = content => {
  if (content != null) {
    return new Buffer.from(content, 'base64').toString();
  }
};

/*
* 去除字符串中的空格
* @param string str 字符串
* @param string type 去除类型 l:左侧 r:右侧 a:前后 default:全部
* return string
* For: exports.trim(' MTIzNDU2 ') => MTIzNDU2
* */
exports.trim = (str, type = 'all') => {
  if (!str) return str;
  switch (type) {
    case 'l':
    case 'left':
      str = str.replace(/^\s*/, '');
      break;
    case 'r':
    case 'right':
      str = str.replace(/(\s*$)/g, '');
      break;
    case 'around':
    case 'a':
      str = str.replace(/^\s+|\s+$/g, '');
      break;
    default:
      str = str.replace(/\s+/g, '');
      break;
  }
  return str;
};

/*
* 用户名验证
* @param string name 用户名
* return bool
* For: exports.check_name('ag_dag') => true
* */
exports.check_name = name => {
  if (!name) return false;
  const reg = new RegExp(/[a-zA-Z0-9_]{3,30}/, 'm');
  const res = reg.exec(name);
  if (!res) return false;
  return res[0] === name;
};

/*
* 手机号码验证
* @param string mobile 手机号码
* return bool
* For: exports.check_mobile('13859548575') => true
* */
exports.check_mobile = mobile => {
  const reg = /(^1[3|4|5|7|8][0-9]{9}$)/;
  if (reg.test(mobile)) {
    return true;
  }
  return false;

};

/*
 * 邮箱格式判断
 * @param string email 邮箱
 * return bool
 * For: exports.check_email('aadg@qq.com') => true
 */
exports.check_email = email => {
  const reg = /^[a-z0-9]([a-z0-9\\.]*[-_]{0,4}?[a-z0-9-_\\.]+)*@([a-z0-9]*[-_]?[a-z0-9]+)+([\.][\w_-]+){1,5}$/i;
  if (reg.test(email)) {
    return true;
  }
  return false;

};

/*
 * ip格式判断
 * @param string ip IP
 * return bool
 * For: exports.check_ip('127.0.0.1') => true
 */
exports.check_ip = ip => {
  const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
  if (reg.test(ip)) {
    return true;
  }
  return false;

};

/*
* 文件读取
* @param string filepath 文件路径
* return string
* For: exports.read_file('./1.txt') => 1
* */
exports.read_file = filepath => {
  if (!filepath) return '';
  const data = fs.readFileSync(filepath);
  return '' + data;
};

/*
* 文件创建
* @param string filepath 文件路径
* @param string data 写入的内容
* @param array op 写入的内容
* return undifind
* For: exports.create_file('E:\node\lession3\egg-server\config\config.json','agdag') => true
* */
exports.create_file = (filepath, data = '', op = {}) => {
  if (!filepath || !data) return false;
  const dir_path = path.dirname(filepath);
  if (fs.existsSync(dir_path)) {
    const op_keys = Object.keys(op);
    op_keys.length ? fs.writeFileSync(filepath, data, op) : fs.writeFileSync(filepath, data);
    return true;
  }
  return false;
};

/*
 * 生成订单号
 * @param $sign 标识
 * return string
 * For: exports.create_code('WX') => WX15368091726110625
 */
exports.create_code = ($sign = '') => {
  const rand = '' + Math.random();
  return $sign + exports.date_to_time('', 1) + rand.slice(2, 6);
};

/*
 * 生成多层目录
 * @param dirpath 多层目录
 * @param mode 目录权限（读写权限），默认0777
 * return bool
 */
exports.create_dirs = (dirpath, mode) => {
  if (!fs.existsSync(dirpath)) {
    let pathtmp;
    dirpath.split(/[/\\]/).forEach(function (dirname) { // 这里指用/ 或\ 都可以分隔目录  如  linux的/usr/local/services   和windows的 d:\temp\aaaa
      if (pathtmp) {
        pathtmp = path.join(pathtmp, dirname);
      } else {
        pathtmp = dirname;
      }
      if (!fs.existsSync(pathtmp)) {
        if (!fs.mkdirSync(pathtmp, mode)) {
          return false;
        }
      }
    });
  }
  return true;
};

/*
 * 删除指定目录下的目录及文件
 * @param targetPath 多层目录
 * return bool
 */
exports.remove_dirs = targetPath => {
  let files = [];
  if (fs.existsSync(targetPath)) {
    files = fs.readdirSync(targetPath);
    files.forEach(function (file) {
      const curPath = targetPath + '/' + file;
      if (fs.statSync(curPath).isDirectory()) { // recurse
        if (!exports.remove_dirs(curPath)) return false;
      } else { // delete file
        fs.unlinkSync(curPath);
      }
    });
    fs.rmdirSync(targetPath);
  }
  return true;
};

/*
 * 随机数生成
 * @param int min 下限值
 * @param int max 上限值
 * return int
 */
function rand(min, max) {
  return Math.random() * (max - min + 1) + min | 0; // 特殊的技巧，|0可以强制转换为整数
}

/*
 * 验证码生成
 * @param int len 验证码长度
 * @param int width 图片宽度
 * @param int height 图片高度
 * return buffer,string 图片流,验证码文本
 */
exports.make_capcha = (len = 4, width = 100, height = 40) => {
  const img = new BMP24(width, height);
  // 白色背景
  img.fillRect(0, 0, width, height, 0xffffff);
  // 绘制圆
  img.drawCircle(rand(0, 100), rand(0, 40), rand(10, 40), rand(0, 0xeeeeee));
  // 边框
  img.drawRect(0, 0, img.w - 1, img.h - 1, rand(0, 0xeeeeee));
  img.fillRect(rand(0, 100), rand(0, 40), rand(10, 35), rand(10, 35), rand(0, 0xeeeeee));
  img.drawLine(rand(0, 100), rand(0, 40), rand(0, 100), rand(0, 40), rand(0, 0xeeeeee));

  // 画曲线
  const w = img.w / 2;
  const h = img.h;
  const color = rand(0, 0xeeeeee);
  const y1 = rand(-5, 5); // Y轴位置调整
  const w2 = rand(10, 15); // 数值越小频率越高
  const h3 = rand(4, 6); // 数值越小幅度越大
  const bl = rand(1, 5);
  for (let i = -w; i < w; i += 0.1) {
    const y = Math.floor(h / h3 * Math.sin(i / w2) + h / 2 + y1);
    const x = Math.floor(i + w);
    for (let j = 0; j < bl; j++) {
      img.drawPoint(x, y + j, color);
    }
  }

  const p = 'ABCDEFGHKMNPQRSTUVWXYZ3456789';
  let str = '';
  for (let i = 0; i < len; i++) {
    str += p.charAt(parseInt(Math.random() * p.length));
  }
  // 绘制文本
  const fonts = [BMP24.font8x16, BMP24.font12x24, BMP24.font16x32];
  let x = 15,
    y = 8;
  for (let i = 0; i < str.length; i++) {
    const f = fonts[parseInt(Math.random() * fonts.length)];
    y = 8 + rand(-10, 10);
    img.drawChar(str[i], x, y, f, rand(0, 0x333344));
    x += f.w + rand(2, 8);
  }
  return { img: img.getFileData(), text: str };
};

/*
 * 数据单位转换
 * @param int bytes 大小
 * return float
 */
exports.bytes_to_size = bytes => {
  if (bytes === 0) return '0 B';
  const k = 1024; // or 1000
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
};

/*
 * 二维码生成
 * @param string text 生成的文本内容
 * return Stream
 */
exports.create_qrcode = text => {
  const qr_svg = qr.image(text, { type: 'png', margin: 1 });
  // qr_svg.pipe(fs.createWriteStream('qrcode.png'));
  // var svg_string = qr.imageSync(text, { type: 'png' });
  return qr_svg;
};

exports.rand = rand;
